package com.infosys.setl.fp.demo5;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.apache.commons.functor.UnaryFunction;
import org.apache.commons.functor.UnaryProcedure;
import org.apache.commons.functor.core.Constant;
import org.apache.commons.functor.core.collection.FilteredIterator;
import org.apache.commons.functor.core.comparator.IsGreaterThanOrEqual;
import org.apache.commons.functor.core.composite.UnaryCompositeBinaryPredicate;

import com.infosys.setl.fp.demo1.SetlItem;
import com.infosys.setl.fp.demo4.BinaryPredicateUnaryPredicate;

public class TestE {
    public static void main(String[] args) {
        Vector<SetlItem> items = new Vector<SetlItem>();
        for (int i = 0; i < 10; i++) {
            SetlItem item = new SetlItem("item" + i);
            if (i % 2 == 0) {
                item.setPrice(101);
            } else {
                item.setPrice(i);
            }
            items.add(item);
        }
        TestE t = new TestE();
        System.out.println("The sum calculated using External Iterator is: " + t.calcPriceExternalIterator(items));
        System.out.println("The sum calculated using Internal Iterator is: " + t.calcPriceInternalIterator(items));
    }

    public int calcPriceExternalIterator(List<SetlItem> items) {
        int runningSum = 0;
        Iterator<SetlItem> i = items.iterator();
        while (i.hasNext()) {
            int itemPrice = i.next().getPrice();
            if (itemPrice >= 100)
                runningSum += itemPrice;
        }
        return runningSum;
    }

    public int calcPriceInternalIterator(List<SetlItem> items) {
        Iterator<SetlItem> i = items.iterator();
        UnaryFunction<SetlItem, Double> getItemPrice = new UnaryFunction<SetlItem, Double>() {
            public Double evaluate(SetlItem obj) {
                return new Double(obj.getPrice());
            }
        };
        Constant<Double> usd100 = new Constant<Double>(new Double(100));
        BinaryPredicateUnaryPredicate moreThanUSD100 = new BinaryPredicateUnaryPredicate(
                new UnaryCompositeBinaryPredicate<SetlItem, SetlItem>(new IsGreaterThanOrEqual<Double>(), getItemPrice, usd100));
        FilteredIterator<SetlItem> fi = new FilteredIterator<SetlItem>(i, moreThanUSD100);
        Summer summer = new Summer();
//        Algorithms.foreach(fi, summer);//??
        return summer.getSum();
    }

    static class Summer implements UnaryProcedure<SetlItem> {
        private int sum = 0;

        public void run(SetlItem obj) {
            sum += obj.getPrice();
        }

        public int getSum() {
            return sum;
        }
    }
}
